-- Viral Resistance - T-Engine 4 Module
-- Copyright (C) 2010 Mikolai Fajer
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- Mikolai Fajer "yufra"
-- mfajer@gmail.com

require "engine.DamageType"
require "engine.Map"

name = "Code Green"
desc = function(self, who)
	local desc = {}
	if self:isCompleted("report") then
		desc[#desc+1] = "#LIGHT_GREEN#* You reported to the Chief of Virology at Room 6, Biohazard Ward."
	elseif self:isStatus(engine.Quest.FAILED, "report") then
		desc[#desc+1] = "#RED#* You failed to report to the Chief of Virology and he is now dead!"
	else
		desc[#desc+1] = "#SLATE#* Report to Room 6 of the Biohazard Ward."
	end
	if self:isCompleted("anti-virals") then
		desc[#desc+1] = "#LIGHT_GREEN#* You delivered the anti-virals to the Chief of Virology."
	elseif self:isStatus(engine.Quest.PENDING, "anti-virals") then
		desc[#desc+1] = "#SLATE#* Deliver the anti-virals from the nurse's station to the Chief of Virology."
	end
	if self:isCompleted("administer") then
		desc[#desc+1] = "#LIGHT_GREEN#* You helped administer the anti-virals, only to see the patient turn into a violent killing machine."
	end
	if self:isCompleted("lockdown") then
		desc[#desc+1] = "#LIGHT_GREEN#* You initiated the Biohazard Ward lockdown."
	elseif self:isStatus(engine.Quest.PENDING, "lockdown") then
		desc[#desc+1] = "#SLATE#* Initiate the Biohazard Ward lockdown (x marks the spot)."
	elseif self:isStatus(engine.Quest.FAILED, "lockdown") then
		desc[#desc+1] = "#RED#* Remote surveillance had to activate the Biohazard Ward lockdown."
	end
	if self:isCompleted("escape") then
		desc[#desc+1] = "#LIGHT_GREEN#* You escaped into the decontamination room."
	elseif self:isStatus(engine.Quest.PENDING, "escape") then
		desc[#desc+1] = "#SLATE#* You need to escape the Biohazard Ward lockdown."
	elseif self:isStatus(engine.Quest.FAILED, "escape") then
		desc[#desc+1] = "#RED#* You failed to escape the Biohazard Ward lockdown and are stuck inside."
	end
	return table.concat(desc, "\n")
end

on_status_change = function(self, who, status, sub)
	if sub then
		if self:isCompleted("escape") then
			who:setQuestStatus(self.id, engine.Quest.DONE)
		end
	end
end

can_offer = function(self, who)
	for inven_id, inven in pairs(who.inven) do
		for item, o in ipairs(inven) do
			if (o.name == "vial of anti-virus") then return true end
		end
	end
end

collect_antiviral = function(self, who, dialog)
	who:showEquipInven("Offer which item?",
		function(o) return (o.type == "medicine" and o.subtype == "viral") end,
		function(o, inven, item)
			who:setQuestStatus(self, self.COMPLETED, "anti-virals")
			who:removeObject(who:getInven(inven), item)
			game.log("You have no more %s", o:getName{no_count=true, do_color=true})
			return true
		end
	)
end

lock_outer_ward = function(self, who)
	-- Lock the outer ward doors
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "outer" then
			local current_door = game.level.map(v.x, v.y, engine.Map.TERRAIN)
			if current_door.door_locked then
				-- Remove the current_door (or else open doors will still act)
				if game.level:hasEntity(current_door) then
					game.level:removeEntity(current_door)
				end
				-- And replace with the locked door
				local g = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_locked)
				g.define_as = "WARD_DOOR"
				game.zone:addEntity(game.level, g, "terrain", v.x, v.y)
				engine.DamageType:get(engine.DamageType.PHYSICAL).projector(g, v.x, v.y, engine.DamageType.PHYSICAL, 1000)
			end
		end
	end
	-- Open the inner ward doors
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "inner" then
			local current_door = game.level.map(v.x, v.y, engine.Map.TERRAIN)
			if current_door.door_opened then
				local opened = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_opened)
				game.zone:addEntity(game.level, opened, "terrain", v.x, v.y)
			end
		end
	end
end

lock_inner_ward = function(self, who)
	-- Lock the inner ward doors
	local ward_doors = {}
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "inner" then
			local current_door = game.level.map(v.x, v.y, engine.Map.TERRAIN)
			if current_door.door_locked then
				-- Remove the current_door (or else open doors will still act)
				if game.level:hasEntity(current_door) then
					game.level:removeEntity(current_door)
				end
				-- And replace with the locked door
				local g = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_locked)
				g.define_as = "WARD_DOOR"
				game.zone:addEntity(game.level, g, "terrain", v.x, v.y)
				engine.DamageType:get(engine.DamageType.PHYSICAL).projector(g, v.x, v.y, engine.DamageType.PHYSICAL, 1000)
			end
		end
	end
end

unlock_outer_ward = function(self, who)
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "outer" then
			local current_door = game.level.map(v.x, v.y, engine.Map.TERRAIN)
			if current_door.door_unlocked then
				local opened = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_unlocked)
				game.zone:addEntity(game.level, opened, "terrain", v.x, v.y)
			end
		end
	end
end

unlock_inner_ward = function(self, who)
	for i, v in pairs(game.level.spots) do
		if v.type == "biohazard doors" and v.subtype == "inner" then
			local current_door = game.level.map(v.x, v.y, engine.Map.TERRAIN)
			local opened = game.zone:makeEntityByName(game.level, 'terrain', current_door.door_unlocked)
			game.zone:addEntity(game.level, opened, "terrain", v.x, v.y)
		end
	end
end

decontaminate_ward = function(self, who)
	-- Find the starting point
	local start
	for i, v in pairs(game.level.spots) do
		if v.type == "quests" and v.subtype == "decontamination start" then
			start = v
			break
		end
	end
	local check = function(tx, ty)
		local grid = game.level.map(tx, ty, engine.Map.TERRAIN)
		return grid.define_as ~= "WARD_DOOR" and grid.define_as ~= "WALL"
	end
	local apply = function(tx, ty)
		game.level.map:addEffect({name='Decontamination'}, tx, ty, 5,
			engine.DamageType.PHYSICAL, 25, 0, 5, nil,
			{type="decontamination"}, nil, false)
	end
	game:floodFill(start.x, start.y, check, apply)
end

check_escape = function(self, who)
	for i, v in pairs(game.level.spots) do
		if v.type == "quests" and v.subtype == "lockdown safety" then
			local check = function(tx, ty)
				local grid = game.level.map(tx, ty, engine.Map.TERRAIN)
				return grid.define_as ~= "WARD_DOOR" and grid.define_as ~= "WALL"
			end
			local apply = function(tx, ty)
				if tx == who.x and ty == who.y then
					who:setQuestStatus("code_green", engine.Quest.COMPLETED, "escape")
				end
			end
			game:floodFill(v.x, v.y, check, apply)
		end
	end
	if not who:isQuestStatus("code_green", engine.Quest.COMPLETED, "escape") then
		who:setQuestStatus("code_green", engine.Quest.FAILED, "escape")
	end
end